package jmine.tec.datadigester.web.pages.importacao;

import images.ImageResources;

import java.util.Arrays;
import java.util.List;

import jmine.tec.executionlog.dao.ExecutionLogItemDAO;
import jmine.tec.executionlog.domain.ExecutionLog;
import jmine.tec.executionlog.domain.ExecutionLogItem;
import jmine.tec.executionlog.domain.enumx.ExecutionItemStatus;
import jmine.tec.web.pages.HelpTextMessages;
import jmine.tec.web.wicket.component.paging.DAOQueryDataProvider;
import jmine.tec.web.wicket.component.paging.PagingNavigatorContainer;
import jmine.tec.web.wicket.model.DefaultDetachableModel;
import jmine.tec.web.wicket.pages.Template;
import jmine.tec.web.wicket.spring.SpringBeanReference;

import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.util.ListModel;

import bancosys.tec.exception.MessageCreator;
import bancosys.tec.persist.dao.BaseDAOFactory;
import bancosys.tec.persist.hibernate.page.PagingService;
import bancosys.tec.security.annotation.Secure;
import bancosys.tec.security.authorization.UrlPermission;

/**
 * Exibe os itens do execution log.
 * 
 * @author wagner
 */
@Secure(id = "URL_LIST_UPLOAD_ARQUIVOS", permissionType = UrlPermission.class)
public class ExecutionLogItens extends Template {

    private static final int RESULTS_PER_PAGE = 15;

    private ExecutionItemStatus executionItemStatus = ExecutionItemStatus.NOT_OK;

    private ExecutionLog executionLog;

    private final SpringBeanReference<BaseDAOFactory> daoFactory = SpringBeanReference.forName("daoFactory");

    private final SpringBeanReference<PagingService> pagingService = SpringBeanReference.forName("pagingService");

    private transient ExecutionLogItemDAO executionLogItemDAO;

    /**
     * @return the executionLogItemDAO
     */
    public ExecutionLogItemDAO getExecutionLogItemDAO() {
        if (this.executionLogItemDAO == null) {
            this.executionLogItemDAO = this.daoFactory.get().getDAOByClass(ExecutionLogItemDAO.class);
        }
        return this.executionLogItemDAO;
    }

    /**
     * C'tor.
     * 
     * @param executionLog {@link ExecutionLog}
     */
    public ExecutionLogItens(ExecutionLog executionLog) {
        super();
        this.executionLog = executionLog;
        this.initComponents();
    }

    /**
     * Inicializar os componentes da tela.
     */
    private void initComponents() {
        Form<Object> form = new Form<Object>("mainForm");
        this.add(new FeedbackPanel("feedback"));
        form.add(this.createExecutionStatusSelect("statusFiltro"));
        form.add(new SubmitLink("btnFiltrar"));
        this.add(new Link<Object>("btnVoltar") {
            @Override
            public void onClick() {
                this.setResponsePage(Importacao.class);
            }
        });

        DataView<ExecutionLogItem> gridLogItens = new DataView<ExecutionLogItem>("logItens", new ExecutionLogItemDataProvider()) {

            @Override
            protected void populateItem(Item<ExecutionLogItem> item) {
                final ExecutionLogItem executionLogItem = item.getModelObject();
                XsltTransformedExecutionLogItem logItem =
                        new XsltTransformedExecutionLogItem("lstContent", "xsl/servicos.xsl", executionLogItem);
                item.add(logItem);
                item.add(new Label("lstStatus", executionLogItem.getStatus().toString()));

                final ModalWindow modalMensagem = new ModalWindow("modalMensagem");
                modalMensagem.setContent(new ModalPanelMensagemErro(modalMensagem.getContentId(), executionLogItem.getMessage()));
                modalMensagem.setTitle("Detalhe do erro de execução");
                item.add(modalMensagem);
                AjaxLink<Void> linkLupa = new AjaxLink<Void>("showErrorMessage") {
                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        modalMensagem.show(target);
                    }
                };
                boolean hasMessage = executionLogItem.getMessage() != null && !"".equals(executionLogItem.getMessage());
                linkLupa.setVisibilityAllowed(hasMessage);
                linkLupa.add(new Image("lupa_stack", new ResourceReference(ImageResources.class, "magnifier.png")));
                item.add(linkLupa);
            }
        };
        gridLogItens.setItemsPerPage(RESULTS_PER_PAGE);
        this.add(gridLogItens);
        PagingNavigatorContainer paging = new PagingNavigatorContainer("navigator", gridLogItens);
        this.add(paging);
        this.add(form);
    }

    /**
     * Cria o input select.
     * 
     * @param idComponente id do componente
     * @return {@link DropDownChoice}
     */
    private DropDownChoice<ExecutionItemStatus> createExecutionStatusSelect(String idComponente) {
        List<ExecutionItemStatus> modelList = Arrays.asList(ExecutionItemStatus.values());
        ListModel<ExecutionItemStatus> listModel = new ListModel<ExecutionItemStatus>(modelList);
        DropDownChoice<ExecutionItemStatus> select = new DropDownChoice<ExecutionItemStatus>(idComponente, listModel);
        select.setDefaultModel(new PropertyModel<ExecutionItemStatus>(this, "executionItemStatus"));
        select.setNullValid(true);
        return select;
    }

    /**
     * DataProvider utilizado para paginação.
     * 
     * @author Rafael Volpato
     * @date Dec 10, 2010
     */
    private class ExecutionLogItemDataProvider extends DAOQueryDataProvider<ExecutionLogItem> {

        /**
         * Construtor
         */
        public ExecutionLogItemDataProvider() {
            super(RESULTS_PER_PAGE, ExecutionLogItens.this.daoFactory, ExecutionLogItens.this.pagingService);
        }

        /**
         * {@inheritDoc}
         */
        public IModel<ExecutionLogItem> model(ExecutionLogItem object) {
            return new DefaultDetachableModel<ExecutionLogItem>(object);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected List<ExecutionLogItem> makeQuery(BaseDAOFactory baseDaoFactory) {
            return ExecutionLogItens.this.getExecutionLogItemDAO().findByExecutionLogStatus(ExecutionLogItens.this.executionLog,
                    ExecutionLogItens.this.executionItemStatus);
        }
    }

    /**
     * Modal da mensagem de erro.
     * 
     * @author Rafael Volpato
     * @date Dec 9, 2010
     */
    public static class ModalPanelMensagemErro extends Panel {

        /**
         * Construtor.
         * 
         * @param id id
         * @param mensagem mensagem
         */
        public ModalPanelMensagemErro(String id, String mensagem) {
            super(id);
            this.add(new TextArea<String>("mensagem", new Model<String>(mensagem)));
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected MessageCreator getHelpTextCreator() {
        return HelpTextMessages.EXECUTION_LOG_ITENS;
    }
}
